package com.shishi.fast.common.advice;

import com.shishi.fast.common.exception.ApiException;
import com.shishi.fast.common.vo.CommonResponse;
import com.shishi.fast.common.vo.IErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {

    // 定义ExceptionHandler解决未被Controller层吸收的Exception
    @ExceptionHandler(Exception.class)
    public CommonResponse handlerException(Exception ex, HttpServletRequest request) {
        if (ex instanceof ApiException) {
            //自定义的异常
            log.warn("自定义的异常 请求URL:{},错误信息:{}", request.getRequestURI(), ex.getMessage());
            IErrorCode errorCode = ((ApiException) ex).getErrorCode();
            String message = ex.getMessage();
            return CommonResponse.failed(errorCode, message);
        } else if (ex instanceof HttpMessageNotReadableException) {
            //参数缺失异常
            return CommonResponse.validateFailed();
        } else if (ex instanceof MissingServletRequestParameterException) {
            //参数缺失异常
            return CommonResponse.validateFailed(ex.getMessage());
        } else if (ex instanceof MethodArgumentNotValidException) {
            //validation校验参数未通过
            return CommonResponse.validateFailed(Objects.requireNonNull(((MethodArgumentNotValidException) ex).getBindingResult().getFieldError()).getDefaultMessage());
        } else if (ex instanceof BindException) {
            //validation校验参数未通过
            return CommonResponse.validateFailed(((BindException) ex).getAllErrors().get(0).getDefaultMessage());
        } else if (ex instanceof HttpRequestMethodNotSupportedException) {
            //请求方法类型错误
            return CommonResponse.failed("请求方法类型错误");
        } else {
            //未知错误
            log.error("未知错误 请求URL:{},错误信息:{}", request.getRequestURI(), ex.getMessage());
            ex.printStackTrace();
            return CommonResponse.failed("未知错误");
        }
    }
}
